package cc.shacocloud.mirage.bean;

import cc.shacocloud.mirage.bean.exception.BeanException;
import jakarta.inject.Provider;
import org.jetbrains.annotations.Nullable;

import java.util.Iterator;
import java.util.function.Supplier;
import java.util.stream.Stream;


/**
 * 对象提供器，专为注入点设计，允许编程可选性和宽松的非唯一处理
 *
 * @param <T> 对象类型
 */
public interface ObjectProvider<T> extends Provider<T>, Iterable<T> {
    
    /**
     * 返回此工厂管理的对象的实例
     */
    @Override
    T get() throws BeanException;
    
    /**
     * 返回此工厂管理的对象的实例
     *
     * @return Bean 的实例，如果不可用，则为 {@code null}
     * @see #get()
     */
    @Nullable
    default T getIfAvailable() {
        try {
            return get();
        } catch (BeanException ignore) {
            return null;
        }
    }
    
    /**
     * 返回此工厂管理的对象的实例
     *
     * @param defaultSupplier 用于提供默认对象的回调（如果工厂中不存在）
     * @return Bean 的实例，如果没有此类 Bean 可用，则提供的默认对象
     * @see #getIfAvailable()
     */
    default T getIfAvailable(Supplier<T> defaultSupplier) throws BeanException {
        T dependency = getIfAvailable();
        return (dependency != null ? dependency : defaultSupplier.get());
    }
    
    /**
     * 在所有匹配的对象实例上返回 {@link Iterator}，没有特定的排序保证
     *
     * @see #stream()
     */
    @Override
    default Iterator<T> iterator() {
        return stream().iterator();
    }
    
    /**
     * 在所有匹配的对象实例上返回顺序 {@link Stream}，没有特定的排序保证
     *
     * @see #iterator()
     */
    Stream<T> stream();
    
}
